home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Synth / Resonance.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  6KB  |  232 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Resonance.C - Resonance
  5.   Copyright (C) 2002-2005 Nasca Octavian Paul
  6.   Author: Nasca Octavian Paul
  7.  
  8.   This program is free software; you can redistribute it and/or modify
  9.   it under the terms of version 2 of the GNU General Public License 
  10.   as published by the Free Software Foundation.
  11.  
  12.   This program is distributed in the hope that it will be useful,
  13.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.   GNU General Public License (version 2) for more details.
  16.  
  17.   You should have received a copy of the GNU General Public License (version 2)
  18.   along with this program; if not, write to the Free Software Foundation,
  19.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20. */
  21.  
  22. #include <math.h>
  23. #include <stdlib.h>
  24. #include "Resonance.h"
  25.  
  26.  
  27. #include <stdio.h>
  28.  
  29. Resonance::Resonance():Presets(){
  30.     setpresettype("Presonance");
  31.     defaults();
  32. };
  33.  
  34. Resonance::~Resonance(){
  35. };
  36.  
  37.  
  38. void Resonance::defaults(){
  39.     Penabled=0;
  40.     PmaxdB=20;
  41.     Pcenterfreq=64;//1 kHz
  42.     Poctavesfreq=64;
  43.     Pprotectthefundamental=0;
  44.     ctlcenter=1.0;
  45.     ctlbw=1.0;
  46.     for (int i=0;i<N_RES_POINTS;i++) Prespoints[i]=64;
  47. };
  48.  
  49. /*
  50.  * Set a point of resonance function with a value
  51.  */
  52. void Resonance::setpoint(int n,unsigned char p){
  53.     if ((n<0)||(n>=N_RES_POINTS)) return;
  54.     Prespoints[n]=p;
  55. };
  56.  
  57. /*
  58.  * Apply the resonance to FFT data
  59.  */
  60. void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq){
  61.     if (Penabled==0) return;//if the resonance is disabled
  62.     REALTYPE sum=0.0,
  63.          l1=log(getfreqx(0.0)*ctlcenter),
  64.          l2=log(2.0)*getoctavesfreq()*ctlbw;
  65.  
  66.     for (int i=0;i<N_RES_POINTS;i++) if (sum<Prespoints[i]) sum=Prespoints[i];
  67.     if (sum<1.0) sum=1.0;
  68.  
  69.     for (int i=1;i<n;i++){
  70.         REALTYPE x=(log(freq*i)-l1)/l2;//compute where the n-th hamonics fits to the graph
  71.     if (x<0.0) x=0.0;
  72.  
  73.     x*=N_RES_POINTS;
  74.     REALTYPE dx=x-floor(x);x=floor(x);
  75.     int kx1=(int)x; if (kx1>=N_RES_POINTS) kx1=N_RES_POINTS-1;
  76.     int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1;
  77.     REALTYPE y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0;
  78.     
  79.     y=pow(10.0,y*PmaxdB/20.0);
  80.     
  81.     if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0;
  82.     
  83.         fftdata.c[i]*=y;
  84.         fftdata.s[i]*=y;
  85.     };    
  86. };
  87.  
  88. /*
  89.  * Gets the response at the frequency "freq"
  90.  */
  91.  
  92. REALTYPE Resonance::getfreqresponse(REALTYPE freq){
  93.     REALTYPE l1=log(getfreqx(0.0)*ctlcenter),
  94.          l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0;
  95.     
  96.     for (int i=0;i<N_RES_POINTS;i++) if (sum<Prespoints[i]) sum=Prespoints[i];
  97.     if (sum<1.0) sum=1.0;
  98.  
  99.     REALTYPE x=(log(freq)-l1)/l2;//compute where the n-th hamonics fits to the graph
  100.     if (x<0.0) x=0.0;
  101.     x*=N_RES_POINTS;
  102.     REALTYPE dx=x-floor(x);x=floor(x);
  103.     int kx1=(int)x; if (kx1>=N_RES_POINTS) kx1=N_RES_POINTS-1;
  104.     int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1;
  105.     REALTYPE result=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0;
  106.     result=pow(10.0,result*PmaxdB/20.0);
  107.     return(result);
  108. };
  109.  
  110.  
  111. /*
  112.  * Smooth the resonance function
  113.  */
  114. void Resonance::smooth(){
  115.     REALTYPE old=Prespoints[0];
  116.     for (int i=0;i<N_RES_POINTS;i++){
  117.         old=old*0.4+Prespoints[i]*0.6;
  118.     Prespoints[i]=(int) old;
  119.     };
  120.     old=Prespoints[N_RES_POINTS-1];
  121.     for (int i=N_RES_POINTS-1;i>0;i--){
  122.         old=old*0.4+Prespoints[i]*0.6;
  123.     Prespoints[i]=(int) old+1;
  124.     if (Prespoints[i]>127) Prespoints[i]=127;
  125.     };
  126. };
  127.  
  128. /*
  129.  * Randomize the resonance function
  130.  */
  131. void Resonance::randomize(int type){
  132.     int r=(int)(RND*127.0);
  133.     for (int i=0;i<N_RES_POINTS;i++){
  134.     Prespoints[i]=r;
  135.     if ((RND<0.1)&&(type==0)) r=(int)(RND*127.0);
  136.     if ((RND<0.3)&&(type==1)) r=(int)(RND*127.0);
  137.     if (type==2) r=(int)(RND*127.0);
  138.     };
  139.     smooth();
  140. };
  141.  
  142. /*
  143.  * Interpolate the peaks
  144.  */
  145. void Resonance::interpolatepeaks(int type){
  146.     int x1=0,y1=Prespoints[0];
  147.     for (int i=1;i<N_RES_POINTS;i++){
  148.     if ((Prespoints[i]!=64)||(i+1==N_RES_POINTS)){
  149.         int y2=Prespoints[i];
  150.         for (int k=0;k<i-x1;k++){
  151.         float x=(float) k/(i-x1);
  152.         if (type==0) x=(1-cos(x*PI))*0.5;
  153.         Prespoints[x1+k]=(int)(y1*(1.0-x)+y2*x);
  154.         };
  155.         x1=i;
  156.         y1=y2;
  157.     };
  158.     };
  159. };
  160.  
  161. /*
  162.  * Get the frequency from x, where x is [0..1]; x is the x coordinate
  163.  */
  164. REALTYPE Resonance::getfreqx(REALTYPE x){
  165.     if (x>1.0) x=1.0;
  166.     REALTYPE octf=pow(2.0,getoctavesfreq());
  167.     return(getcenterfreq()/sqrt(octf)*pow(octf,x));
  168. };
  169.  
  170. /*
  171.  * Get the x coordinate from frequency (used by the UI)
  172.  */
  173. REALTYPE Resonance::getfreqpos(REALTYPE freq){
  174.     return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq());
  175. };
  176.  
  177. /*
  178.  * Get the center frequency of the resonance graph
  179.  */
  180. REALTYPE Resonance::getcenterfreq(){
  181.     return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0));
  182. };
  183.  
  184. /*
  185.  * Get the number of octave that the resonance functions applies to
  186.  */
  187. REALTYPE Resonance::getoctavesfreq(){
  188.     return(0.25+10.0*Poctavesfreq/127.0);
  189. };
  190.  
  191. void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par){
  192.     if (ctl==C_resonance_center) ctlcenter=par;
  193.     else ctlbw=par;
  194. };
  195.  
  196.  
  197.  
  198.  
  199. void Resonance::add2XML(XMLwrapper *xml){
  200.     xml->addparbool("enabled",Penabled);
  201.     
  202.     if ((Penabled==0)&&(xml->minimal)) return;
  203.  
  204.     xml->addpar("max_db",PmaxdB);
  205.     xml->addpar("center_freq",Pcenterfreq);
  206.     xml->addpar("octaves_freq",Poctavesfreq);
  207.     xml->addparbool("protect_fundamental_frequency",Pprotectthefundamental);
  208.     xml->addpar("resonance_points",N_RES_POINTS);
  209.     for (int i=0;i<N_RES_POINTS;i++){
  210.     xml->beginbranch("RESPOINT",i);
  211.         xml->addpar("val",Prespoints[i]);
  212.     xml->endbranch();
  213.     };
  214. };
  215.  
  216.  
  217. void Resonance::getfromXML(XMLwrapper *xml){
  218.     Penabled=xml->getparbool("enabled",Penabled);
  219.  
  220.     PmaxdB=xml->getpar127("max_db",PmaxdB);
  221.     Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq);
  222.     Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq);
  223.     Pprotectthefundamental=xml->getparbool("protect_fundamental_frequency",Pprotectthefundamental);
  224.     for (int i=0;i<N_RES_POINTS;i++){
  225.     if (xml->enterbranch("RESPOINT",i)==0) continue;
  226.         Prespoints[i]=xml->getpar127("val",Prespoints[i]);
  227.       xml->exitbranch();
  228.     };
  229. };
  230.  
  231.  
  232.